using System;
using System.Collections.Generic;
using System.Text;
using KukaDataComCommon;

namespace KukaDataCom
{
    public class CommandProcessor : MarshalByRefObject, ICommandController
    {

        #region Command-Enum

        public enum KukaCommands
        {
           PTP = 100,
           LIN = 101,
           CIRC = 102,
           CIRC_ANGLE = 103,
           PTP_AX = 111,
           GRAB = 50
        }

        #endregion

        #region Eigenschaften

        private readonly SerialQueueHandler queue;
        public SerialQueueHandler Queuer
        {
            get { return queue; }
        }

        private IEventForwarder eventForwarder = null;
        public IEventForwarder EventForwarder
        {
            set { eventForwarder = value; }
            get { return eventForwarder; }
        }

        #endregion

        #region Konstruktor

        public CommandProcessor(SerialQueueHandler queue)
        {
            this.queue = queue;
            Queuer.PositionUpdated += queuer_PositionUpdated;
        }

        private void queuer_PositionUpdated(object sender, PositionUpdatedEventArgs e)
        {
            if (EventForwarder != null)
                EventForwarder.OnPositionUpdated(e);
        }

        #endregion

        #region events

        public event Action<string> JobEnqueued;

        protected void OnJobEnqueued(Modus modus, string description)
        {
            if (JobEnqueued != null)
                JobEnqueued(modus.Name + " (" + description + ")");
        }

        #endregion

        #region Interface Implementierung

        public void PTP(Position end)
        {
           Modus modus = Queuer.GetModus('b');
           if (modus != null && end != null)
           {
              Int16[] ints = new Int16[] { Convert.ToInt16(KukaCommands.PTP),
                                             end.AxialUniqueness.Spin,
                                             end.AxialUniqueness.Turn};
              char[] chars = new char[0];
              float[] floats = new float[] {end.Location.X,
                                              end.Location.Y,
                                              end.Location.Z,
                                              end.Orientation.A,
                                              end.Orientation.B,
                                              end.Orientation.C};

              Queuer.Enqueue(modus, ints, chars, floats);
              OnJobEnqueued(modus, "PTP " + end);
           }
        }
        public void PTP(AxisPosition end)
        {
           Modus modus = Queuer.GetModus('a');
           if (modus != null)
           {

              Int16[] ints = new Int16[] { Convert.ToInt16(KukaCommands.PTP_AX) };

              char[] chars = new char[0];
              float[] floats = new float[] { end.A1, end.A2, end.A3, end.A4, end.A5, end.A6 };

              Queuer.Enqueue(modus, ints, chars, floats);
              OnJobEnqueued(modus, "PTP " + end.ToString());
           }
        }


        public void LIN(Position end)
        {
            Modus modus = Queuer.GetModus('a');
           if (modus == null || end == null) return;
           var ints = new Int16[] { Convert.ToInt16(KukaCommands.LIN) };
           var chars = new char[0];
           var floats = new float[] {end.Location.X,
                                         end.Location.Y,
                                         end.Location.Z,
                                         end.Orientation.A,
                                         end.Orientation.B,
                                         end.Orientation.C};

           Queuer.Enqueue(modus, ints, chars, floats);
           OnJobEnqueued(modus, "LIN " + end);
        }

        public void CIRC(Position end, Location help, float circularAngle)
        {
            Modus modus = Queuer.GetModus('c');
            if (modus != null && end != null)
            {
                Int16[] ints = new Int16[] { Convert.ToInt16(KukaCommands.CIRC_ANGLE) };
                char[] chars = new char[0];
                float[] floats = new float[] {end.Location.X,
                                              end.Location.Y,
                                              end.Location.Z,
                                              end.Orientation.A,
                                              end.Orientation.B,
                                              end.Orientation.C,
                                              help.X,
                                              help.Y,
                                              help.Z,
                                              circularAngle};

                Queuer.Enqueue(modus, ints, chars, floats);
                OnJobEnqueued(modus, "CIRC " + end + ":" + help);
            }
        }

        public void CIRC(Position end, Location help)
        {
            Modus modus = Queuer.GetModus('c');
            if (modus != null && end != null)
            {
                Int16[] ints = new Int16[] { Convert.ToInt16(KukaCommands.CIRC) };
                char[] chars = new char[0];
                float[] floats = new float[] {end.Location.X,
                                              end.Location.Y,
                                              end.Location.Z,
                                              end.Orientation.A,
                                              end.Orientation.B,
                                              end.Orientation.C,
                                              help.X,
                                              help.Y,
                                              help.Z,};

                Queuer.Enqueue(modus, ints, chars, floats);
                OnJobEnqueued(modus, "CIRC " + end + ":" + help);
            }
        }



        public void getCurrentPosition()
        {
           Modus modus = Queuer.GetModus('v');
           if (modus != null)
           {
              Int16[] ints = new Int16[0];
              char[] chars = new char[0];
              float[] floats = new float[0];

              Queuer.Enqueue(modus, ints, chars, floats);
              OnJobEnqueued(modus, "get Position");
           }
        }
        public void getCurrentAxisPosition()
        {
           Modus modus = Queuer.GetModus('g');
           if (modus != null)
           {
              Int16[] ints = new Int16[0];
              char[] chars = new char[0];
              float[] floats = new float[0];

              Queuer.Enqueue(modus, ints, chars, floats);
              OnJobEnqueued(modus, "get AxisPosition");
           }
        }

        public void GRAB(bool close)
        {
            Modus modus = Queuer.GetModus('m');
            if (modus != null)
            {
                Int16[] ints = new Int16[2] {Convert.ToInt16(KukaCommands.GRAB), 
                                            (Int16) (close ? 1 : 0)};
                char[] chars = new char[0];
                float[] floats = new float[0];

                Queuer.Enqueue(modus, ints, chars, floats);
                OnJobEnqueued(modus, "GRAB " + (close ? "close" : "open"));
            }
        }

        #endregion

    }
}